<!--  -->
<template>
  <div class="linuxCode">
    <div class="head my-flex flex-y-center flex-x-between">
      <!-- 倒计时组建 -->
      <count-down
        ref="counDownRef"
        :current-time="currentTime"
        :start-time="startTime"
        :end-time="endTime"
        :exercise-time-status="exerciseTimeStatus"
        @startCallback="onStartExerciseTime"
        @endCallback="onEndExerciseTime"
      />

      <div class="btnGroup my-flex flex-y-center flex-x-between">

        <div class="miniGroup ">
          <el-button
            :disabled="!isExerciseTime"
            :loading="loading"
            class="SmallUploadReportBtn"
            @click="onRefreshLinux"
          >
            <el-image
              class="SmallUploadReportBtnIcon"
              style="width: 16px; height: 16px"
              :src="require('@/assets/linux/refresh_icon.png')"
            />
            重置</el-button>

          <el-button
            :loading="loading"
            :disabled="!isExerciseTime"
            class="SmallUploadReportBtn"
            @click="onScreentshot"
          >
            <el-image
              class="SmallUploadReportBtnIcon"
              style="width: 16px; height: 16px"
              :src="require('@/assets/linux/screenshot_icon.png')"
            />
            截图保存</el-button>
        </div>

        <el-button
          type="primary"
          class="uploadReportBtn"
          @click="onUploadReport"
        >
          <el-image
            class="uploadReportIcon"
            style="width: 13px; height: 14px"
            :src="require('@/assets/report/uploadReportIcon.png')"
          />
          提交报告</el-button>
      </div>
    </div>

    <div
      id="content"
      v-loading="loading"
      :element-loading-text="loadingText"
      class="content my-flex flex-x-center flex-y-center"
    >
      <div v-show="isXtermOpen === false" class="contentControl">
        <el-image :src="openLinuxImgSrc" style="width:336px;height:212px;display:block" />
        <p v-show="!isExerciseTime" class="timeErrorTip">未到指定时间，无法开启</p>
        <el-button :class="{'contentBtnActiveMargin': isExerciseTime}" :loading="loading" :disabled="!isExerciseTime" type="primary" @click="handleOpenLinux">开启虚拟机</el-button>
      </div>
      <Xterm
        v-show="isXtermOpen === true"
        id="xtermContainer"
        ref="xtermContainer"
        :is-xterm-open="isXtermOpen"
        :loading="loading"
        class="contentXterm"
        @onAbnormalShutdown="XtermAbnormalShutdown"
        @onCloseLinux="onCloseLinux"
      />
    </div>

    <uploadReport ref="uploadReport" :visible="isShowUploadReport" @close="onCloseUploadReport" />
  </div>
</template>

<script>
import { saveAs } from 'file-saver'
import CountDown from './countdown.vue'
import { toBlob } from 'html-to-image'
import Xterm from './xterm.vue'
import uploadReport from './uploadReport'
import { getSystemSetup } from '@/api/config'

export default {
  name: '',
  // import引入的组件需要注入到对象中才能使用
  components: {
    CountDown,
    Xterm,
    uploadReport
  },
  data() {
    // 这里存放数据
    return {
      loadingText: '',
      isShowUploadReport: false,
      linuxId: '',
      loading: false,
      datePicckerTime: [],
      currentTime: 0,
      startTime: 0,
      endTime: 0,
      exerciseTimeStatus: null, // 虚拟机状态，0 永远关闭虚拟机 1 永远开启 2开启并且指定时间
      isExerciseTime: false, // 是否在开考时间
      isXtermOpen: false // 是否显示虚拟机DOM
    }
  },
  // 监听属性 类似于data概念
  computed: {
    openLinuxImgSrc() {
      // 判断时间是
      return this.isExerciseTime === true ? require('@/assets/linux/startLinux.png') : require('@/assets/linux/endLinux.png')
    }
  },
  // 监控data中的数据变化
  watch: {},
  // 生命周期 - 创建完成（可以访问当前this实例）
  async created() {
  },
  // 生命周期 - 挂载完成（可以访问DOM元素）
  async mounted() {
    await this.loadExerciseTime()
  },
  // 生命周期 - keep-alive
  async activated() {

  },
  // 方法集合
  methods: {
    async onCloseLinux() {
      const logout = await this.logoutLinux()
      if (logout !== true) { return false }

      // 异常关闭页面显示重新链接
      this.isXtermOpen = false
    },
    // xterm异常关闭
    XtermAbnormalShutdown() {
      this.$messageOnce({
        message: '虚拟机已被关闭',
        type: 'error',
        duration: 2000
      })
      // 异常关闭页面显示重新链接
      this.isXtermOpen = false
    },
    // 获取开考时间
    async loadExerciseTime() {
      this.loading = true
      try {
        const { code, data } = await getSystemSetup()
        if (code === 0) {
          this.initExerciseTime(data)
        }
        this.loading = false
      } catch (error) {
        console.error(error)
      } finally {
        this.loading = false
      }
    },
    initExerciseTime(data) {
      // 找到符合条件的数据
      const res = data.filter((item) => {
        return item.config_name === 'open_docker_date'
      })
      // console.log(res)
      const { config_type, config_value } = res[0]
      if (config_type === 0) {
        // 选者关闭虚拟机
        this.startTime = 0
        this.endTime = 0
        this.currentTime = 0
        this.exerciseTimeStatus = 0
      } else if (config_type === 1 && config_value === '') {
        // 选者永远开启虚拟机
        this.startTime = 0
        this.endTime = 0
        this.currentTime = 0
        this.exerciseTimeStatus = 1
        // 考试时到
        this.isExerciseTime = true
      } else if (config_type === 1 && config_value !== '') {
        // 选择指定时间开启
        const arrData = config_value.split('~')
        console.log(arrData)
        this.startTime = Number(arrData[0])
        this.endTime = Number(arrData[1])
        this.currentTime = new Date().getTime()
        // console.log(Number(arrData[0]), Number(arrData[1]), this.currentTime)
        this.exerciseTimeStatus = 2
      } else {
        this.$messageOnce.error('初始化数据失败')
        return false
      }
    },
    // 重置linux
    async onRefreshLinux() {
      // linuxId 如果为空代表没有开启过虚拟机
      const linuxId = this.linuxId

      // 没有ID证明没有开启过虚拟机
      if (linuxId === '') {
        this.$messageOnce({
          message: '请先开启虚拟机',
          type: 'error',
          duration: 2000
        })
        // 开放打开虚拟机页面
        this.isXtermOpen = false
        return false
      }

      // 如果开启给一个确认框，取消/确认
      this.$confirm('您的操作将会关闭Linux虚拟机，之前的操作将不会被保留，是否继续？')
        .then(async _ => {
          // 注销
          const logout = await this.logoutLinux()
          if (logout !== true) { return false }

          // 重新开启
          await this.handleOpenLinux()
        })
        .catch(_ => { })
    },
    // 时间截止
    async onEndExerciseTime(isEnd) {
      this.isExerciseTime = false

      // 判断是否有开启Linux
      const linuxId = this.linuxId
      if (linuxId === '') { return false }
      const logout = await this.logoutLinux()
      if (logout !== true) { return false }
      this.isXtermOpen = false
    },
    // 监听开考时间
    onStartExerciseTime(isStart) {
      this.isExerciseTime = isStart
    },
    // 开启虚拟机
    async handleOpenLinux() {
      const responseJSON = await this.getLinuxId()
      if (typeof (responseJSON) === 'undefined') return false

      // 设置iframeSrc
      let iframeSrc
      if (process.env.VUE_APP_LINUX_URL === 'edu.docker.wenchu.cc') {
        iframeSrc = `wss://${process.env.VUE_APP_LINUX_URL}/ws?id=${this.linuxId}&ip=${responseJSON.data}`
      } else {
        iframeSrc = `ws://${process.env.VUE_APP_LINUX_URL}/ws?id=${this.linuxId}&ip=${responseJSON.data}`
      }
      this.$refs.xtermContainer.initTerm(iframeSrc, responseJSON)

      // 打开虚拟机
      this.isXtermOpen = true
    },
    // 保存截图
    onScreentshot() {
      this.loading = true
      this.loadingText = '截图保存中'
      const MY_INFO_STR = localStorage.getItem('MY_INFO')
      const { real_name } = JSON.parse(MY_INFO_STR)
      var node = document.getElementById('content')

      toBlob(node)
        .then((blob) => {
          const time = new Date().getTime()
          saveAs(blob, `${real_name}Linux截图${time}.png`)
          this.loading = false
        })
    },
    // 获取时间 TODO
    async getExerciseTime() {

    },
    // 获取虚拟机Id
    async getLinuxId() {
      this.loading = true
      this.loadingText = '虚拟机加载中'
      // 获取缓存Id
      const linuxData = localStorage.getItem('linuxData') || ''
      let postData
      // 不为空赋值
      if (linuxData !== '' && linuxData !== undefined) {
        const responseJSON = JSON.parse(linuxData)
        // 赋值
        this.linuxId = responseJSON.id
        postData = this.linuxId
      } else {
        postData = 'null'
      }

      const fetchUrl = process.env.VUE_APP_LINUX_URL === 'edu.docker.wenchu.cc' ? `https://${process.env.VUE_APP_LINUX_URL}?id=${postData}` : `http://${process.env.VUE_APP_LINUX_URL}?id=${postData}`

      return await fetch(fetchUrl,
        {
          method: 'post'
        })
        .then(response => response.json())
        .then(res => {
          const { id } = res
          this.loading = false

          // 正常逻辑
          if (id !== null && id !== '') {
            this.linuxId = id
            const retrunData = { ...res, encoding: res.message }
            // 设置缓存
            localStorage.setItem('linuxData', JSON.stringify(retrunData))

            // Xterm 需要
            return retrunData
          } else {
            throw new Error('无法获取Id')
          }
        })
        .catch(err => {
          this.loading = false
          this.$messageOnce({
            message: '开启异常',
            type: 'error',
            duration: 2000
          })
          // 清除缓存
          localStorage.removeItem('linuxData')
          console.log('Request Failed', err)
        })
    },
    // 注销linux
    async logoutLinux() {
      // 如果没有开启，
      const linuxId = this.linuxId
      if (linuxId === '' || linuxId === undefined) return false

      this.loading = true
      this.loadingText = '虚拟机注销中'
      const postData = new FormData()
      postData.append('id', this.linuxId)

      const fetchUrl = process.env.VUE_APP_LINUX_URL === 'edu.docker.wenchu.cc' ? `https://${process.env.VUE_APP_LINUX_URL}/close` : `http://${process.env.VUE_APP_LINUX_URL}/close`
      return await fetch(fetchUrl,
        {
          method: 'post',
          body: postData
        })
        .then(response => response.json())
        .then(res => {
          this.loading = false
          const { data, code } = res
          if (code === 0) {
            // 清除缓存
            localStorage.removeItem('linuxData')
            return data
          }
        })
        .catch(err => {
          this.loading = false
          console.log('Request Failed', err)
        })
    },
    countDownStart() {
      // this.$refs.counDownRef.gogogo()
    },
    onUploadReport() {
      this.isShowUploadReport = true
      this.$refs.uploadReport.getReportGroupList()
    },
    onCloseUploadReport() {
      this.isShowUploadReport = !this.isShowUploadReport
    }
  },
  // 进入页面前
  beforeRouteEnter(to, from, next) {
    next(vm => {

    })
  },
  // 离开页面前
  beforeRouteLeave(to, from, next) {
    next()
  }
}
</script>
<style lang="scss" scoped>
.linuxCode {
  width: 100%;
  height: 100%;
  p {
    margin: 0;
    padding: 0;
  }
  .head {
    height: 50px;
    background-color: #F7F7F7;
    padding: 0 40px;

    .countdown {

      &Subtitle {
        @include FifthFont(#2C2C2C,500);
        .clockIcon {
          width: 14px;
          height: 14px;
          margin-right: 10px;
        }
      }

      &Detail {
        margin-left: 20px;
        @include FifthFont($MainColor,500);
      }
    }

    .btnGroup {
      width: 368px;
      .uploadReportBtn {
        @include UploadReportBtn();
      }
      .SmallUploadReportBtn {
        @include SmallUploadReportBtn();

      }

      .miniGroup {
        .el-button:hover, .el-button:focus {
          border-color: #EEEEEE;
          background-color: #EEEEEE;
        }
        .SmallUploadReportBtn:nth-child(2) {
          margin-left: 40px;
        }
      }
    }
  }

  .content {
    height: calc(100vh - 120px);

    &Control {
      text-align: center;
      .el-button {
        margin-top: 25px;
        border-radius: 6px;
      }
      .el-button--primary.is-disabled, .el-button--primary.is-disabled:hover, .el-button--primary.is-disabled:focus, .el-button--primary.is-disabled:active {
        background-color: #999999;
        border-color: #999999;
      }
    }

    &Xterm {
      width: 100%;
      height: 100%;
    }

    &BtnActiveMargin {
      margin-top: 60px!important;
    }

    .timeErrorTip {
      margin-top: 15px;
      @include FourthFont(#999999,500);
    }
  }
}
</style>
